package ext.generic.doc;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.Locale;
import java.util.PropertyResourceBundle;
import java.util.Vector;

import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import wt.doc.WTDocument;
import wt.doc.WTDocumentConfigSpec;
import wt.doc.WTDocumentDependencyLink;
import wt.doc.WTDocumentHelper;
import wt.doc.WTDocumentMaster;
import wt.doc.WTDocumentStandardConfigSpec;
import wt.doc.WTDocumentUsageLink;
import wt.fc.Persistable;
import wt.fc.PersistenceHelper;
import wt.fc.QueryResult;
import wt.inf.container.WTContained;
import wt.inf.container.WTContainer;
import wt.inf.library.WTLibrary;
import wt.lifecycle.LifeCycleHelper;
import wt.lifecycle.LifeCycleManaged;
import wt.lifecycle.State;
import wt.pdmlink.PDMLinkProduct;
import wt.query.QuerySpec;
import wt.query.SearchCondition;
import wt.session.SessionHelper;
import wt.type.ClientTypedUtility;
import wt.util.WTException;
import wt.util.WTMessage;
import wt.util.WTProperties;
import wt.vc.Iterated;
import wt.vc.config.ConfigHelper;
import wt.vc.config.ConfigSpec;
import wt.vc.config.LatestConfigSpec;
import wt.vc.struct.StructHelper;
import ext.com.iba.IBAUtil;
/**
 * 文档流程中使用到的后台方法类
 */
public class DocWorkflowUtil
{
    public static boolean VERBOSE;
    private static String WFGUIDE = "wfGuide";
    public static WTProperties wtproperties;
    private static Locale locale = null;
    private static String CLASSNAME= DocWorkflowUtil.class.getName();
    private static final String RESOURCE = "ext.generic.wfaugment.processors.processorsResource";
	public DocWorkflowUtil() 
	{
	}
    static
    {
        wtproperties = null;
        try
        {
            wtproperties = WTProperties.getLocalProperties();
            VERBOSE = (WTProperties.getLocalProperties()).getProperty("ext.guide.workflow.verbose", false);
        }
        catch (Throwable throwable)
        {
            throw new ExceptionInInitializerError(throwable);
        }
    }
	/**
	 *输出调试信息
	 */
	private static void outDebugInfo(String info)
	{
		if (VERBOSE)
			System.out.println(CLASSNAME + "$$$$$" + info);
	}

    /**
     * 批量恢复被移除的随签文档
     */
    public static void resumeReviewDocState(Vector oldv, Vector newv, WTDocument document)
    {
        Vector inworkv = new Vector();
        Vector waitreviewv = new Vector();
        String modifer = document.getModifierName();
        for (int i = 0; i < oldv.size(); i++)
        {
            if (!newv.contains(oldv.elementAt(i)))
            {
                WTDocument doc = (WTDocument) (oldv.elementAt(i));
                String docmodifer = doc.getModifierName();
                if (docmodifer.equalsIgnoreCase(modifer))
                {
                    inworkv.add(doc);
                }
                else
                {
                    waitreviewv.add(doc);
                }
            }
        }
        if (inworkv.size() > 0)
        {
            setLifeCycleState(inworkv, "INWORK");
        }
        if (waitreviewv.size() > 0)
        {
            setLifeCycleState(waitreviewv, "SUBMITO");
        }
    }
    /**
     *根据文档主数据(master)获取最新版本的文档
     * @param doc_master
     * @return
     * @throws WTException
     */
    public static WTDocument getLatestWTDocument(WTDocumentMaster doc_master) throws WTException
    {
        Iterated iter = null;
        boolean flag = false;
        LatestConfigSpec latestconfigspec = new LatestConfigSpec();
        QueryResult queryresult = ConfigHelper.service.filteredIterationsOf(doc_master, latestconfigspec);
        if (queryresult.size() <= 0)
        {
            ConfigSpec configspec = ConfigHelper.service.getDefaultConfigSpecFor(WTDocumentMaster.class);
            queryresult = ConfigHelper.service.filteredIterationsOf(doc_master, configspec);
        }

        while (queryresult.hasMoreElements() && (!flag))
        {
            iter = (Iterated) (queryresult.nextElement());
            flag = iter.isLatestIteration();
        }
        return (WTDocument) iter;
    }
    /**
     *判断指定的对象是否在数组之中
     * @param objVector 数组
     * @param destination 指定的对象
     * @return
     * @throws WTException
     */
    public static boolean isPersistableInobjVector(Vector objVector, Persistable destination) throws WTException
    {
        if ((objVector == null) || (objVector.size() <= 0))
            return false;
        if (objVector.contains(destination))
        {
            return true;
        }
        boolean flag = false;
        for (int i = 0; i < objVector.size(); i++)
        {
            flag = PersistenceHelper.isEquivalent((Persistable) objVector.elementAt(i), destination);
            if (flag)
                return flag;
        }
        return flag;
    }
    /**
     *批量设置生命周期状态
     * @param lcmList 对象列表
     * @param toState 目标状态
     */
    public static void setLifeCycleState(Vector lcmList, String toState)
    {
        for (int i = 0; i < lcmList.size(); i++)
        {
            LifeCycleManaged lcm = (LifeCycleManaged) lcmList.elementAt(i);
            String currentlcmState = lcm.getLifeCycleState().toString();
            if (currentlcmState.equals("RELEASED"))
                continue;
            try
            {
                LifeCycleHelper.service.setLifeCycleState(lcm, State.toState(toState));
            }
            catch (WTException wte)
            {
                wte.printStackTrace();
            }
        }
    }
    /**
     *检查指定编码的文档是否存在
     * @param docNumber
     * @return
     * @throws WTException
     */
    public static boolean isExist(String docNumber) throws WTException
    {
        if (docNumber.equals("") || docNumber == null)
            return false;

        QueryResult qr = null;

        try
        {
            QuerySpec qs = new QuerySpec(wt.doc.WTDocumentMaster.class);
            SearchCondition sc = new SearchCondition(WTDocumentMaster.class, "number", SearchCondition.LIKE, docNumber);
            qs.appendSearchCondition(sc);

            qr = PersistenceHelper.manager.find(qs);

            if (qr.hasMoreElements())
                return true;
            else
                return false;
        }
        catch (WTException wte)
        {
            wte.printStackTrace();
        }
        return false;
    }
    /**
     *根据编号获取最新版本的文档
     * @param docNumber
     * @return
     * @throws WTException
     */
    public static WTDocument getWTDocumentByNumber(String docNumber) throws WTException
    {
        if (!isExist(docNumber))
            return null;

        WTDocument doc = null;
        try
        {
            QuerySpec qs = new QuerySpec(WTDocumentMaster.class);
            SearchCondition sc = new SearchCondition(WTDocumentMaster.class, "number", SearchCondition.LIKE, docNumber);
            qs.appendSearchCondition(sc);
            QueryResult qr = PersistenceHelper.manager.find(qs);
            while (qr.hasMoreElements())
            {
                WTDocumentMaster master = (WTDocumentMaster) qr.nextElement();
                doc = getLatestWTDocument(master);
                break;
            }
        }
        catch (WTException wte)
        {
            wte.printStackTrace();
        }
        return doc;
    }
    /**
     *根据文档获取其相关的文档
     * @param doc
     * @return
     * @throws WTException
     */
    public static Vector getRelatedDocsOfDoc(WTDocument doc) throws WTException
    {
        Vector docVec = new Vector();
        Vector docTemp = new Vector();
        QueryResult queryResult = PersistenceHelper.manager.navigate(doc, "describedBy", WTDocumentDependencyLink.class, true);
        while (queryResult.hasMoreElements())
        {
            WTDocument doc2 = (WTDocument) queryResult.nextElement();
            if (doc2.isLatestIteration())
            {
                docVec.add(doc2);
            }
        }
        queryResult = PersistenceHelper.manager.navigate(doc, "describes", WTDocumentDependencyLink.class, true);
        while (queryResult.hasMoreElements())
        {
            WTDocument doc1 = (WTDocument) queryResult.nextElement();
            if (doc1.isLatestIteration())
                docVec.add(doc1);
        }
        return docVec;
    }
    /**
     *根据文档递归获取其所有的子文档;
     * @param doc
     * @return
     * @throws WTException
     */
    public static Vector getsubDocListByDoc(WTDocument doc) throws WTException
    {
        Vector doclist = new Vector();
        Vector vec = getFirstLevelSubDocListByDoc(doc);
        for (int i = 0; i < vec.size(); i++)
        {
            WTDocument subdoc = (WTDocument) vec.elementAt(i);
            if (!isPersistableInobjVector(doclist, subdoc))
                doclist.addElement(subdoc);
            Vector tempDoclist = getsubDocListByDoc(subdoc);
            for (int j = 0; j < tempDoclist.size(); j++)
            {
                WTDocument child = (WTDocument) tempDoclist.elementAt(j);
                if (!isPersistableInobjVector(doclist, child))
                {
                    doclist.add(child);
                }
            }
        }
        return doclist;
    }
    /**
     *根据文档获取其第一层子文档,即直接子文档
     * @param doc
     * @return
     * @throws WTException
     */
    public static Vector getFirstLevelSubDocListByDoc(WTDocument doc) throws WTException
    {
        Vector doclist = new Vector();
        ConfigSpec latestconfigspec = new LatestConfigSpec();
        WTDocumentConfigSpec config = WTDocumentHelper.service.findWTDocumentConfigSpec();
        WTDocumentStandardConfigSpec standardConfig = config.getStandard();
        latestconfigspec = standardConfig;
        QueryResult qr = StructHelper.service.navigateUsesToIteration(doc, WTDocumentUsageLink.class, false, latestconfigspec);
        while (qr != null && qr.hasMoreElements())
        {
            Persistable apersistable[] = (Persistable[]) qr.nextElement();
            WTDocumentUsageLink docLink = (WTDocumentUsageLink) apersistable[0];
            Object uses = apersistable[1];
            WTDocument subdoc = null;
            if (uses instanceof WTDocumentMaster)
            {
                subdoc = getLatestWTDocument((WTDocumentMaster) uses);
            }
            else
                subdoc = (WTDocument) uses;
            if (subdoc != null && !isPersistableInobjVector(doclist, subdoc))
                doclist.add(subdoc);
        }
        return doclist;
    }
    /**
     *判断指定的文档是否跟随其关联的零部件走流程;
     * @param pbo 文档
     * @param activityName 流程任务节点名称
     * @param sheetName 文档流程配置文件(excel)的页,该页中定义了文档流程的配置信息
     * @return
     * @throws WTException
     */
    public static boolean isReviewDoc(Persistable pbo, String activityName, String sheetName) throws WTException
    {
        try
        {
            boolean isPartDoc = false;
            String wfConfigFilePath = getConfigFilePath(pbo);
            XSSFWorkbook wb = new XSSFWorkbook(new FileInputStream(wfConfigFilePath));
            String detailType = "";
            String bigType = "";
            XSSFSheet sheet = wb.getSheet(sheetName);
            Iterator rows = sheet.rowIterator();
            int rowNumber = 1;
            int nActivityCol = 0;
            String cellValue = "";
            XSSFRow row;
            XSSFCell cell;
            if (pbo instanceof WTDocument)
            {
                WTDocument doc = (WTDocument) pbo;
                bigType = getDocType(doc);
                outDebugInfo("bigType====>"+bigType);
                String docType = getPropertiesValue("ext.generic.wfaugment.wfaugment", "wf.doc.smallType");
                outDebugInfo("docType====>"+docType);
                detailType = (String)IBAUtil.getIBAValue(doc, docType);
                outDebugInfo("detailType====>"+detailType);
                if (detailType == null)
                  detailType = "-";
                String langMark;
                int columnMark;
                if (detailType == null || detailType.length() == 0)
                {
                    langMark = bigType;
                    columnMark = 0;
                }
                else
                {
                    langMark = detailType;
                    columnMark = 1;
                }
                row = (XSSFRow) rows.next();
                do
                {
                    if (!rows.hasNext())
                        break;
                    cell = row.getCell((short) columnMark);
                    if (cell != null)
                    {
                        cellValue = cell.getStringCellValue().trim();
                        if (cellValue.equals(langMark))
                        {
                            rowNumber = row.getRowNum();
                            break;
                        }
                    }
                    row = (XSSFRow) rows.next();
                }
                while (true);
            }
            else
            {
                rowNumber = 1;
            }
            row = sheet.getRow(0);
            for (int i = 0; i < row.getLastCellNum(); i++)
            {
                cell = row.getCell((short) i);
                if (cell == null)
                    continue;
                cellValue = cell.getStringCellValue().trim();
                if (!cellValue.equals(activityName))
                    continue;
                nActivityCol = i;
                break;
            }
            XSSFRow row1 = sheet.getRow(rowNumber);
            cell = row1.getCell((short) nActivityCol);
            if (cell != null)
            {
                String roleValue = cell.getStringCellValue();
                roleValue = roleValue.trim();
                if (roleValue.equalsIgnoreCase("Y"))
                {
                    isPartDoc = true;
                }
            }
            return isPartDoc;
        }
        catch (IOException ioexception)
        {
            throw new WTException(ioexception);
        }
    }
    /**
     *获取文档流程的配置文件路径
     * @param pbo
     * @return
     * @throws IOException
     * @throws WTException
     */
    public static String getConfigFilePath(Persistable pbo) throws IOException, WTException
    {
        String configFilePath = "";
        String propertyName = "";
        if (pbo instanceof WTContained)
        {
            WTContained containedObj = (WTContained) pbo;
            WTContainer container = containedObj.getContainer();
            String orgName = container.getOrganizationName();
            String containerName = container.getName();
            if (container instanceof WTLibrary)
            {
                if (pbo instanceof WTDocument)
                {
                    propertyName = "ext." + orgName + "." + "WTLibrary." + containerName + "." + "doc." + WFGUIDE;
                    System.out.println("propertyName=" + propertyName);
                    configFilePath = wtproperties.getProperty(propertyName, "");
                }
            }
            if (container instanceof PDMLinkProduct)
            {
                if (pbo instanceof WTDocument)
                {
                    propertyName = "ext." + orgName + "." + "PDMLinkProduct." + containerName + "." + "doc." + WFGUIDE;
                    System.out.println("propertyName=" + propertyName);
                    configFilePath = wtproperties.getProperty(propertyName, "");
                    System.out.println("configFilePath=" + configFilePath);
                }
            }
            if (configFilePath == null || configFilePath.length() == 0)
            {
                propertyName = "ext." + orgName + "." + "default." + "doc" + "." + WFGUIDE;
                configFilePath = wtproperties.getProperty(propertyName, "");
                System.out.println("configFilePath=" + configFilePath);
            }
        }
        configFilePath = configFilePath.replace('/', File.separatorChar);
        configFilePath = configFilePath.replace('\\', File.separatorChar);
        if (configFilePath.length() == 0)
        {
            Locale locale = SessionHelper.manager.getLocale();
            throw new WTException(propertyName + WTMessage.getLocalizedMessage(RESOURCE, "11", null, locale));
        }
        System.out.println("configFilePath2=" + configFilePath);
        return configFilePath;
    }
    /**
     *获取文档软类型(即大类)的显示名称
     * @param doc
     * @return
     * @throws IOException
     * @throws WTException
     */
    public static String getDocType(WTDocument doc) throws IOException, WTException
    {
        String docType = "";
        Locale locale = SessionHelper.manager.getLocale();
        docType = ClientTypedUtility.getLocalizedTypeName(doc, locale);
        return docType;
    }
    /**
     *获取指定的properties文件中的属性值
     * @param propertityFile
     * @param keyInProperties
     * @return
     * @throws WTException
     */
    public static String getPropertiesValue(String propertityFile, String keyInProperties) throws WTException
    {
        String valueInProperties = "";

        PropertyResourceBundle prBundle = (PropertyResourceBundle) PropertyResourceBundle.getBundle(propertityFile);
        try
        {
            byte[] temp = null;
            temp = keyInProperties.getBytes("GB2312");
            keyInProperties = new String(temp, "ISO-8859-1");
            temp = prBundle.getString(keyInProperties).getBytes("ISO-8859-1");
            valueInProperties = new String(temp, "GB2312");
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return valueInProperties.trim();

    }

    public static void main(String args[])
    {
        String number = args[0];
        Vector vec = new Vector();
        Vector subvec = new Vector();
        try
        {
            WTDocument doc = getWTDocumentByNumber(number);
            if (doc == null)
            {
                System.out.println("不存在该编号的文档！");
                System.exit(0);
            }
            boolean flag = isReviewDoc(doc, "随签", "doc");
            ;
            System.out.println("&&&&&flag=" + flag);
            /*
			 * vec=getRelatedDocsOfDoc(doc); System.out.println("vec="+vec);
			 * System.out.println("vec.size="+vec.size()); for(int
			 * i=0;i<vec.size();i++) { WTDocument
			 * document=(WTDocument)vec.elementAt(i); }
			 */
            /*
			 * if(doc instanceof WTContained) { System.out.println("*******");
			 * WTContained containedObj = (WTContained)doc; WTContainer
			 * container = containedObj.getContainer(); String orgName =
			 * container.getOrganizationName();
			 * System.out.println("&&orgname="+orgName); String
			 * containerName=container.getName();
			 * System.out.println("&&containerName="+containerName); }
			 */
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        /*
		 * Vector vec1=new Vector(); Vector vec2=new Vector(); vec1.add("123");
		 * vec1.add("456"); vec2=(Vector)vec1.clone(); vec2.add("789");
		 * System.out.println("vec1="+vec1); System.out.println("vec2="+vec2);
		 */
    }
}
